
#pragma once

#include <vector>
#include "OgreMath/OgreVector3.h"
#include "Ray.h"

class Projection
{
private:
	int mWidth, mHeight;
	float mProjectionPlaneWidth, mProjectionPlaneHeight;
public:
	Projection(int width, int height, float fov) : mWidth(width), mHeight(height)
	{
		float whRatio = mWidth/(float)mHeight;

		/*
		a = fov / 2
		      /|  
		     / |   
		    /  |    
		   /   | height
		  /    | 
		 /\    |
		/a_)___|
		   z=1
		tan(a) = height/z
		=> height = tan(a) *z
		*/	

		mProjectionPlaneHeight = std::tan(fov*0.5f);
		mProjectionPlaneWidth = mProjectionPlaneHeight*whRatio;
	}

	/// Converts a pixel in ([0, 1], [0, 1]) to a ray.
	Ray pixelToRay(float screenX, float screenY) const
	{
		float x = ((2.0f*screenX-mWidth) / mWidth) * mProjectionPlaneWidth;
		float y = ((2.0f*screenY-mHeight) / mHeight) * mProjectionPlaneHeight;
		float z = 1.0f;
		Ogre::Vector3 dir(x, y, z);
		dir.normalise();
		return Ray(Ogre::Vector3(0,0,0), dir);
	}

	int getWidth() const { return mWidth; }
	int getHeight() const { return mHeight; }
};